#include <iostream>
#include <functional>
#include <memory>
#include <string>
#include "include/muduo/net/TcpClient.h"
#include "include/muduo/net/EventLoopThread.h"
#include "include/muduo/net/TcpConnection.h"
#include "include/muduo/base/CountDownLatch.h"

class EchoClient
{
public:
    EchoClient(const std::string& serverIp, const uint16_t serverPort)
        : _tcpClient(_loopThread.startLoop(), muduo::net::InetAddress(serverIp, serverPort), "EchoClient")
        , _latch(1) //等待次数
    {
        _tcpClient.setConnectionCallback(std::bind(&EchoClient::onConnection, this, std::placeholders::_1));
        _tcpClient.setMessageCallback(std::bind(&EchoClient::onMessage, this, std::placeholders::_1, 
            std::placeholders::_2, std::placeholders::_3));
    }

    void connect()
    {
        _tcpClient.connect();
        _latch.wait(); //等待连接建立成功
    }

    bool send(const std::string& msg)
    {
        if(!_conn->connected()) return false; //连接异常，不发送
        _conn->send(msg);
        return true;
    }

    ~EchoClient()
    {}
private:
    void onConnection(const muduo::net::TcpConnectionPtr& conn)
    {
        if(conn->connected()) 
        {
            _conn = conn;
            _latch.countDown(); //唤醒等待
        }
        else
        {
            _conn.reset(); //关闭连接
        }
    }

    void onMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buffer, muduo::Timestamp timestamp)
    {
        std::cout << buffer->retrieveAllAsString() << std::endl;
    }
private:
    muduo::net::EventLoopThread _loopThread;
    muduo::net::TcpClient _tcpClient;
    muduo::net::TcpConnectionPtr _conn;
    muduo::CountDownLatch _latch;
};

int main()
{
    std::unique_ptr<EchoClient> echoClient = std::make_unique<EchoClient>("127.0.0.1", 9090);
    echoClient->connect();

    while(true) 
    {
        std::string buffer;
        std::cin >> buffer;
        echoClient->send(buffer);
    }

    return 0;
}